package view;

import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;

/**
 * Created by ilioili on 2014/12/12.
 */
public class SearchKeyView extends ViewGroup {
    int maxLine = Integer.MAX_VALUE;
    private int itemHeight;
    private int itemHeightSpec = 0;
    private ArrayList<View> itemList = new ArrayList<View>();
    private int itemWidthSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
    private int layoutId;
    private Map<Object, TextView> map = new HashMap<Object, TextView>();
    private View moreView;
    private OnItemClickListener onItemClickListener;
    private OnClickListener itemListener = new OnClickListener() {
        @Override
        public void onClick(View v) {
            onItemClickListener.onItemClick(v, itemList.indexOf(v));
        }
    };
    private int textViewId;
    private LinkedList<View> viewCachePool;
    public SearchKeyView(Context context) {
        this(context, null);
    }

    public SearchKeyView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public SearchKeyView(final Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    public View addItem(Object obj, String title) {
        View item = getStyledItem(obj, title);
        item.setFocusable(false);
        item.setOnClickListener(itemListener);
        item.setClickable(true);
        itemList.add(item);
        addView(item);
        setFocusable(true);
        setFocusableInTouchMode(true);
        requestFocus();
        return item;
    }

    private View getStyledItem(Object obj, String title) {
        View v = null;
        if (null != viewCachePool && !viewCachePool.isEmpty()) {
            v = viewCachePool.poll();
        } else {
            v = LayoutInflater.from(getContext()).inflate(layoutId, null);
        }
        v.setSelected(false);
        v.setTag(obj);
        TextView tv = (TextView) v.findViewById(textViewId);
        tv.setText(title);
        map.put(obj, tv);
        return v;
    }

    public TextView getTextView(Object obj) {
        return map.get(obj);
    }

    public void removeItem(Object obj) {
        for (int i = 0; i < getChildCount(); i++) {
            if (getChildAt(i).getTag() == obj) {
                removeViewAt(i);
                break;
            }
        }
    }

    public void reset() {
        if (null != viewCachePool) {
            viewCachePool.addAll(itemList);
        }
        for (View v : itemList) {
            removeView(v);
        }
        itemList.clear();
    }

    public void setConfig(int maxLine, int moreViewResource, OnClickListener listener) {
        this.maxLine = maxLine;
        moreView = LayoutInflater.from(getContext()).inflate(moreViewResource, null);
        moreView.setClickable(true);
        moreView.setOnClickListener(listener);
        addView(moreView);
    }

    public void setItemResourceId(int layoutId, int textViewId) {
        this.layoutId = layoutId;
        this.textViewId = textViewId;
    }

    public void setOnItemClickListener(OnItemClickListener listener) {
        onItemClickListener = listener;
    }

    public void setViewCachePool(LinkedList<View> viewCachePool) {
        this.viewCachePool = viewCachePool;
    }


    public interface OnItemClickListener {
        void onItemClick(View clickedChildView, int position);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        itemHeight = MeasureSpec.getSize(getLayoutParams().height);
        itemHeightSpec = MeasureSpec.makeMeasureSpec(itemHeight, MeasureSpec.EXACTLY);
        measureChildren(itemWidthSpec, itemHeightSpec);
        int width = MeasureSpec.getSize(widthMeasureSpec);
        int curHeight = 0;
        int curWidth = 0;
        int lineNum = 0;
        boolean newLine = true;
        View lastView = null;
        if (null != moreView) {
            moreView.layout(0, 0, 0, 0);
        }
        for (View v : itemList) {
            int end = curWidth + v.getMeasuredWidth();
            if (end > width) {
                lineNum++;
                if (lineNum == maxLine) {
                    lastView.setVisibility(View.INVISIBLE);
                    if (null != moreView) {
                        moreView.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), itemHeightSpec);
                        if (lastView.getLeft() + moreView.getMeasuredWidth() > width) {
                            moreView.measure(MeasureSpec.makeMeasureSpec(width - lastView.getLeft(), MeasureSpec.EXACTLY), itemHeightSpec);
                        }
                        moreView.layout(lastView.getLeft(), lastView.getTop(), lastView.getLeft() + moreView.getMeasuredWidth(), lastView.getBottom());
                    }
                    break;
                }
                if (newLine) {
                    layoutChild(v, getPaddingLeft(), curHeight, width, curHeight + itemHeight);
                    newLine = true;
                    curHeight += itemHeight;
                    curWidth = getPaddingLeft();
                } else {
                    curHeight += itemHeight;
                    if (v.getMeasuredWidth() > width) {
                        layoutChild(v, getPaddingLeft(), curHeight, width, curHeight + itemHeight);
                        curHeight += itemHeight;
                        curWidth = getPaddingLeft();
                        newLine = true;
                    } else {
                        layoutChild(v, getPaddingLeft(), curHeight, v.getMeasuredWidth() + getPaddingLeft(), curHeight + itemHeight);
                        curWidth = v.getMeasuredWidth() + getPaddingLeft();
                    }
                }

            } else {
                layoutChild(v, curWidth, curHeight, end, curHeight + itemHeight);
                curWidth = end;
                newLine = false;
            }
            lastView = v;
        }
        setMeasuredDimension(width, curHeight + itemHeight);
    }

    private void layoutChild(View v, int l, int t, int r, int b) {
        v.layout(l, t, r, b);
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
    }
}
